home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Plus Special 25
/
AMIGAplus Sonderheft 25 (2000)(Falke)(DE)(Track 1 of 4)[!].iso
/
PublicDomain
/
Anwendungen
/
Altabber
/
src
/
Altabber.c
next >
Wrap
C/C++ Source or Header
|
1999-04-01
|
25KB
|
926 lines
/* Altabber, n. He who performs an `Alt-Tab' action.
**
** Version 1.5 (1.4.99) © Mfc.
**
** Compile with DICE:
** dcc -mi -mRR -pi Altabber.c NewReadArgs.c
**
** The "fixed-keys" version of Altabber (without argument/tooltypes parsing)
** can be obtained with:
** dcc -mi -mRR -DFIXEDKEYS -pi Altabber.c
**
** To enable debugging output, simply add "-DDEBUG"
**
*/
#include "Altabber.h"
#ifndef FIXEDKEYS
#include <NewReadArgs.h>
#endif
/// Defines
/* Messages we will receive from the Cx filter: */
#define WINTAB 1 /* Cycle thru windows */
#define SCRTAB 2 /* Cycle thru screens */
#define UPSTROKE 8 /* Select this item */
/* Max string lengths: */
#define MAX_TITLE_LEN 80
#define MAX_HOTKEY_LEN 40
/* Some macros: */
#define CURRENTLY_ACTIVE_SCR IntuitionBase->ActiveScreen
#define CURRENTLY_ACTIVE_WIN IntuitionBase->ActiveWindow
#define FIRST_AVAILABLE_SCR IntuitionBase->FirstScreen
#define FIRST_AVAILABLE_WIN IntuitionBase->ActiveScreen->FirstWindow
/* Pretty obvious :-) */
#define JAM1 0
#define JAM2 1
/* This is a clearly impossible hotkey */
#define DUMMY_KEY "Ctrl LAmiga RAmiga NumPad *"
/* A couple of largely used macros: */
#define xalloc(s) AllocVec(s, 0)
#define xfree(a) FreeVec(a)
#ifdef DEBUG
#define D(x) x
#else
#define D(x)
#endif
#define TEMPLATE "WQ=WIN_QUAL/K,WK=WIN_KEY/K," \
"SQ=SCR_QUAL/K,SK=SCR_KEY/K," \
"CX_PRIORITY/N/K," \
"COLOR1/N/K,COLOR2/N/K,"\
"AA=AUTOACTIVATE/S" /* Not yet fully functional! */
///
/// Globals
/* The options (either CLI parameters or icon ToolTypes) */
/* are stored in the Opt struct. Some defaults are given here: */
const int def_pri = -5;
const int def_color1 = 1;
const int def_color2 = 2;
struct {
STRPTR win_qual, win_key;
STRPTR scr_qual, scr_key;
int *pri;
int *color1, *color2;
int aa; /* Not yet fully functional! */
} Opt = {
"LAmiga", "Tab",
"LAmiga", "Shift Tab",
&def_pri,
&def_color1, &def_color2,
0 /* Not yet fully functional! */
};
/* These are extern since we let the compiler care for */
/* opening library, replying WB, etc. */
extern struct IntuitionBase *IntuitionBase;
extern struct WBStartup *_WBMsg;
/* Has our window been opened? */
int Win_open = 0;
int Scr_open = 0;
/* Each item (either scr or win) is stored in a struct */
/* like this. Multiple records are then linked together */
/* in a single chain. */
struct record {
void *id;
unsigned char title[MAX_TITLE_LEN];
int len;
int width;
struct record *next;
};
struct record *First_item; /* Head of the chain */
struct record *Special_item; /* Some magic stuff usad by the OMM */
struct record *Displayed_item; /* The currently displayed item */
struct record *Active_item; /* The item which was active when the user */
/* pressed the hotkey the first time */
/* Gfx Globals: all the global variable which are related to gfx */
/* (window, rastport, fonts, etc.) are placed in a single global struct */
struct {
struct Window *win;
struct RastPort *rp;
struct TextFont *font;
int font_height;
int font_baseline;
int max_width;
int top_corner, left_corner;
} GG = {NULL};
/* OMM (Olivier's Memory Method) */
void *Last_active_win = NULL;
void *Last_active_scr = NULL;
struct MsgPort *mp; /* the port where we will receive all the msgs */
ULONG Sigbits; /* signals we will wait for */
/* Every Cx must have an Object called a broker: */
CxObj *Broker;
/* The special filters used to know when the user releases the qualifier key. */
/* They can't be "normal" hotkeys as they imply "upstroke", which the Cx */
/* interface doen't recognize. */
/* magic class code cmask qual qmask synonyms*/
IX scr_ix = { IX_VERSION, IECLASS_RAWKEY, 0, 0xffff, 0, 0, 0 };
IX win_ix = { IX_VERSION, IECLASS_RAWKEY, 0, 0xffff, 0, 0, 0 };
///
/// Prototypes
int open_window(void);
void close_window(void);
void display_next(void);
int create_scrlist(void);
int create_winlist(void);
void raise_scr(void);
void raise_win(void);
void dispose_list(void);
void handle(void);
int copy_title(STRPTR, STRPTR);
int qualcode(STRPTR);
CxObj *AttachFilter(STRPTR, ULONG);
int ShowError(STRPTR);
///
#define BROKERVERSION "Altabber 1.5 ©1999 Mfc."
static const STRPTR version = "$VER: Altabber 1.5 (1.4.99)";
/// main()
/* ¯¯¯¯¯¯
*/
#ifdef _DCC
__stkargs
#endif
void _main()
{
int error = 0;
#ifndef FIXEDKEYS
/* Read the arguments/tooltypes */
struct NewRDArgs nrda = {
TEMPLATE,
NULL,
NULL,
(LONG *) &Opt,
-1,
TRUE,
/* other fields = NULL */
};
error = NewReadArgs(_WBMsg, &nrda);
#endif
if (error == 0)
{
unsigned char win_hotkey[MAX_HOTKEY_LEN];
unsigned char scr_hotkey[MAX_HOTKEY_LEN];
#ifdef DEBUG
Printf("win_qual=%s\n", Opt.win_qual);
Printf("win_key=%s\n", Opt.win_key);
Printf("scr_qual=%s\n", Opt.scr_qual);
Printf("scr_key=%s\n", Opt.scr_key);
Printf("pri=%ld\n", *Opt.pri);
Printf("color1,2=%ld,%ld\n", *Opt.color1, *Opt.color2);
Printf("aa=%ld\n", Opt.aa);
#endif
/* Try to interpret the options and to build an adequate */
/* IX filter for every qualifier */
win_ix.ix_Code = IECODE_UP_PREFIX | qualcode(Opt.win_qual);
scr_ix.ix_Code = IECODE_UP_PREFIX | qualcode(Opt.scr_qual);
/* Build the win hotkey as the union of the "_QUAL" option */
/* and the "_KEY" option */
strcpy(win_hotkey, Opt.win_qual);
strcat(win_hotkey, " ");
strcat(win_hotkey, Opt.win_key);
/* Build the scr hotkey as the union of the "_QUAL" option */
/* and the "_KEY" option */
strcpy(scr_hotkey, Opt.scr_qual);
strcat(scr_hotkey, " ");
strcat(scr_hotkey, Opt.scr_key);
#ifdef DEBUG
Printf("win_hotkey=|%s|\n", win_hotkey);
Printf("scr_hotkey=|%s|\n", scr_hotkey);
Printf("win_ix.ix_Code=%lx\n", win_ix.ix_Code);
Printf("scr_ix.ix_Code=%lx\n", scr_ix.ix_Code);
#endif
if (mp=CreateMsgPort())
{
/* Create the broker */
struct NewBroker nb = {
NB_VERSION,
"Altabber",
BROKERVERSION,
"Windoze-like Alt-Tab function",
NBU_UNIQUE | NBU_NOTIFY,
0, *Opt.pri, 0, 0
};
nb.nb_Port = mp;
Sigbits = SIGBREAKF_CTRL_C | (1L << mp->mp_SigBit);
if (Broker=CxBroker(&nb, &error))
{
/* Now we start to attach things to the broker. */
/* First of all the two filters which intercept */
/* the Amiga+Tab and Amiga+Shift+Tab strokes */
if (AttachFilter(win_hotkey, WINTAB) &&
AttachFilter(scr_hotkey, SCRTAB))
{
/* Add the special filter which intercept */
/* the release of the Amiga key. To do this, */
/* first build a normal filetr with a dummy hotkey, */
/* then replace the dummy hotkey with the actual IX */
CxObj *x = AttachFilter(DUMMY_KEY, UPSTROKE);
if (x)
{
SetFilterIX(x, &win_ix);
/* Do the same with the scr upstroke filter, */
/* but only if it's different from the win one */
if (scr_ix.ix_Code != win_ix.ix_Code)
{
x = AttachFilter(DUMMY_KEY, UPSTROKE);
if (x)
SetFilterIX(x, &scr_ix);
}
if (x)
{
/* If everithing's ok, activate the broker */
ActivateCxObj(Broker, 1);